home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Frameworks
/
Grant's CGI Framework 1.0b14
/
Util
/
FileUtil.c
< prev
next >
Wrap
Text File
|
1996-04-12
|
7KB
|
253 lines
/*****
*
* FileUtil.c
*
* This is a support file for "Grant's CGI Framework".
* Please see the license agreement that accompanies the distribution package
* for licensing details.
*
* Copyright ©1995,1996 by Grant Neufeld
* grant@acm.com
* http://arpp.carleton.ca/grant/mac/grantscgi/
*
*****/
#include "MyConfiguration.h"
#include <Aliases.h>
#include <string.h>
#include "compiler_stuff.h"
#include "DebugUtil.h"
#include "MemoryUtil.h"
#include "FileUtil.h"
/*** LOCAL VARIABLES ***/
/*** LOCAL CONSTANTS ***/
/*** LOCAL PROTOTYPES ***/
/*** FUNCTIONS ***/
/* the data returned will not be null terminated */
OSErr
FileReadBytes ( short fileRef, long start, long lineLength, char *theLine, long *bytesRead )
{
OSErr theErr;
long lineSize;
my_assert ( fileRef != nil, "\pmyFileReadBytes: fileRef is nil" );
my_assert ( lineLength != nil, "\pmyFileReadBytes: lineLength is nil" );
my_assert ( theLine != NULL, "\pmyFileReadBytes: theLine ptr is NULL" );
my_assert ( bytesRead != NULL, "\pmyFileReadBytes: bytesRead ptr is NULL" );
theErr = SetFPos ( fileRef, fsFromStart, start );
if ( theErr != noErr )
{
goto EXIT_FUNCTION;
}
lineSize = lineLength - 1;
theErr = FSRead ( fileRef, bytesRead, theLine );
if ( (theErr != noErr) && (theErr != eofErr) )
{
theLine[nil] = nil;
goto EXIT_FUNCTION;
}
/* make sure the string is terminated */
theLine[lineSize] = nil;
EXIT_FUNCTION:
return (theErr == eofErr)? noErr : theErr;
} /* FileReadBytes */
/* Finder alias handling */
#pragma mark -
/* From Apple Developer Support: New Technical Notes;
"FL 29/30? Resolving Alias File Quietly"
Set the last Boolean (mountRemoteVols) to true to avoid the resolving of
aliases that map to unmounted volumes. You definitly want to do that
because you don't want the user interface for mounting remote volumes
coming up on servers when there's no one around to deal with that interface. */
pascal OSErr
ResolveAliasFileMountOption ( FSSpec *fileFSSpec, Boolean resolveAliasChains,
Boolean *targetIsFolder, Boolean *wasAliased, Boolean mountRemoteVols )
{
/* maximum number of aliases to resolve before giving up */
#define MAXCHAINS 10
short myResRefNum;
Handle alisHandle;
FSSpec initFSSpec;
Boolean updateFlag;
Boolean foundFlag;
Boolean wasAliasedTemp;
Boolean specChangedFlag;
short chainCount;
OSErr retCode;
if ( (fileFSSpec == NULL) || (targetIsFolder == nil) || (wasAliased == nil) )
{
return paramErr;
}
initFSSpec = *fileFSSpec; /* so FSSpec can be restored in case of error */
chainCount = MAXCHAINS; /* circular alias chain protection */
myResRefNum = -1; /* resource file not open */
*targetIsFolder = foundFlag = specChangedFlag = false;
/* loop through chain of alias files */
do
{
chainCount--;
/* check if FSSpec is an alias file or a directory.
note that targetIsFolder => NOT wasAliased */
retCode = IsAliasFile ( fileFSSpec, wasAliased, targetIsFolder );
if ( (retCode != noErr) || !(*wasAliased) )
{
break;
}
/* get the resource file reference number */
myResRefNum = FSpOpenResFile ( fileFSSpec, fsCurPerm );
retCode = ResError ();
if ( myResRefNum == -1 )
{
break;
}
/* the first 'alis' resource in the file is the appropriate alias */
alisHandle = Get1IndResource ( rAliasType, 1 );
retCode = ResError ();
if ( alisHandle == nil )
{
break;
}
/* load the resource explicitly in case SetResLoad(FALSE) */
LoadResource ( alisHandle );
retCode = ResError ();
if ( retCode != noErr )
{
break;
}
retCode = FollowFinderAlias ( fileFSSpec, (AliasHandle)alisHandle, mountRemoteVols, fileFSSpec, &updateFlag );
/* FollowFinderAlias returns nsvErr if volume not mounted */
if ( retCode == noErr )
{
if ( updateFlag )
{
/* the resource in the alias file needs updating */
ChangedResource ( alisHandle );
WriteResource ( alisHandle );
}
specChangedFlag = true; /* in case of error, restore file spec */
retCode = IsAliasFile ( fileFSSpec, &wasAliasedTemp, targetIsFolder );
if ( retCode == noErr )
{
/* we're done unless it was an alias file and we're following a chain */
foundFlag = !(wasAliasedTemp && resolveAliasChains);
}
}
CloseResFile( myResRefNum );
myResRefNum = -1;
} while ( (retCode == noErr) && (chainCount > nil) && !(foundFlag) );
/* return file not found error for circular alias chains */
if ( (chainCount == nil) && !(foundFlag) )
{
retCode = fnfErr;
}
/* if error occurred, close resource file and restore the original FSSpec */
if ( myResRefNum != -1 )
{
CloseResFile ( myResRefNum );
}
if ( (retCode != noErr) && specChangedFlag )
{
*fileFSSpec = initFSSpec;
}
return retCode;
} /* ResolveAliasFileMountOption */
/* sets aliasFileFlag if the FSSpec points to an alias file;
sets folderFlag if the FSSpec points to a folder */
pascal OSErr
IsAliasFile ( const FSSpec *fileFSSpec, Boolean *aliasFileFlag, Boolean *folderFlag )
{
CInfoPBRec myCInfoPBRec;
OSErr retCode;
if ( (fileFSSpec == NULL) || (aliasFileFlag == nil) || (folderFlag == nil) )
{
return paramErr;
}
*aliasFileFlag = *folderFlag = false;
/* get the item's catalog information */
myCInfoPBRec.hFileInfo.ioCompletion = NULL;
myCInfoPBRec.hFileInfo.ioNamePtr = (StringPtr)(fileFSSpec->name);
myCInfoPBRec.hFileInfo.ioVRefNum = fileFSSpec->vRefNum;
myCInfoPBRec.hFileInfo.ioDirID = fileFSSpec->parID;
myCInfoPBRec.hFileInfo.ioFVersNum = nil;
/* MFS compatibility, see TN #204 */
myCInfoPBRec.hFileInfo.ioFDirIndex = nil;
retCode = PBGetCatInfoSync ( &myCInfoPBRec );
/* set aliasFileFlag if the item is not a directory and the aliasFile bit is set */
if ( retCode == noErr )
{
/* check directory bit */
if ( (myCInfoPBRec.hFileInfo.ioFlAttrib & ioDirMask) != nil )
{
*folderFlag = true;
}
/* check isAlias bit */
else if ( (myCInfoPBRec.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) != nil )
{
*aliasFileFlag = true;
}
}
return retCode;
} /* IsAliasFile */
/* this is included in the newer header files, so has been removed */
#if 0
/* FollowFinderAlias resolves an alias taken from a Finder alias file,
updating the alias record (but not the alias resource in the file) if necessary.
Warning: This trap is used internally by Apple Computer, Inc.
It has not been tested for use by application software.
While we do not anticipate any problems, it is the responsibility of the developer
to ensure that it operates appropriately and reliably for their application. */
pascal OSErr
FollowFinderAlias ( const FSSpec *fromFile, AliasHandle alias, Boolean logon, FSSpec *target, Boolean *wasChanged )
= {0x700F, 0xA823}; /* MOVEQ #$0F,D0; _AliasDispatch; */
#endif /* 0 */
/***** EOF *****/